#include "SPI.h"

#if SPI_EN

#if !USE_SOFTWARE_SPI
static data uint8_t spi_txd_len = 0;
static bit spi_busy = 0;
static uint8_t *spi_buffer_ptr = NULL;
#endif

void spi_init_gpio(int8_t sclk, int8_t mosi, int8_t miso, int8_t cs)
{
	if (sclk != -1)
	{
		gpio_write((uint8_t)sclk, 0);
		gpio_mode((uint8_t)sclk, OUTPUT_PUSH_PULL);
	}
	if (mosi != -1)
		gpio_mode((uint8_t)mosi, OUTPUT_PUSH_PULL);
	if (miso != -1)
		gpio_mode((uint8_t)miso, OUTPUT_PUSH_PULL);
	if (cs != -1)
	{
		gpio_write((uint8_t)cs, 1);
		gpio_mode((uint8_t)cs, OUTPUT_PUSH_PULL);
	}
}
#if USE_SOFTWARE_SPI
void spi_begin_trans_default()
{
	SPI_CS_IO = 0;
}
void spi_end_trans_default()
{
	SPI_CS_IO = 1;
}

void spi_begin_trans(uint8_t cs)
{
	gpio_write(cs, LOW);
}
void spi_end_trans(uint8_t cs)
{
	gpio_write(cs, HIGH);
}

#else
void spi_begin(spi_clk clk, SPI_GPIO_NUM _io)
{
	P_SW1 &= 0xf3;
	P_SW1 |= _io << 2;
	SPCTL = 0xdc | clk; // 使能SPI主机模式
	SPSTAT = 0xc0;		// 清中断标志
	// IE2 |= 0x02;		//使能SPI中断

#ifdef STC8A_DMA_TYPE
	P_SW2 |= 0X80;
	DMA_SPI_STA = 0X00;
	DMA_SPI_CFG = 0X40;
	DMA_SPI_CR = 0X81;
	DMA_SPI_CFG2 = 0X00;
	P_SW2 &= ~0X80;
#endif
}
#ifdef STC8A_DMA_TYPE
void dpi_dma_write(uint8_t *dat, uint8_t size)
{
	uint8_t xdata *tmp = dat;
	P_SW2 |= 0X80;
	DMA_SPI_AMT = size - 1;
	DMA_SPI_TXA = tmp;
	DMA_SPI_CR |= 0x40;
	DMA_SPI_STA = 0x00;
	while (!(DMA_SPI_STA & 0x01))
		;
	P_SW2 &= ~0X80;
}
#endif

void spi_end()
{
	IE2 &= ~0X02;
	SPCTL = 0X00;
}

#endif

#if USE_SOFTWARE_SPI

// void spi_write_bits(uint8_t *dat, uint8_t len)
// {
// 	uint8_t i = 0, j = *dat;
// 	while (len--)
// 	{
// 		if ((j & 0x80) == 0X80)
// 			SPI_MOSI_IO = 1;
// 		else
// 			SPI_MOSI_IO = 0;
// 		SPI_SCLK_IO = 1;
// 		j <<= 1;
// 		SPI_SCLK_IO = 0;
// 	}
// }

#else
void spi_set_clk(spi_clk clk)
{
	SPCTL &= ~0x03;
	SPCTL |= clk;
}
#endif

void spi_write(uint8_t dat)
{
#if USE_SOFTWARE_SPI
	idata uint8_t i = 8, j = dat;
	while (i--)
	{
		if ((j & 0x80) == 0X80)
			SPI_MOSI_IO = 1;
		else
			SPI_MOSI_IO = 0;
		SPI_SCLK_IO = 1;
		j <<= 1;
		SPI_SCLK_IO = 0;
	}
#else
	// while (spi_busy)
	// 		;
	// spi_busy = 1;
	SPDAT = dat;
	while (!(SPSTAT & 0X80))
		;
	SPSTAT = 0Xc0;
#endif
}

// 向指定从机地址指定寄存器地址reg_add写入一个字节value
void spi_write16(uint16_t value)
{
	spi_write(value >> 8);
	spi_write(value & 0xff);
}

// 向指定从机地址指定寄存器地址reg_add起始连续写入dat指向的内容，长度len字节
void spi_write_bytes(uint8_t *dat, uint8_t len)
{
#if USE_SOFTWARE_SPI
	idata uint8_t _len = len;
	while (_len--)
		spi_write(*dat++);
#else
	while (len--)
	{
		SPDAT = *dat++;
		while (!(SPSTAT & 0X80))
			;
		SPSTAT = 0Xc0;
	}
#endif
}

#endif
